package com.yuw.dz.dao;

import java.sql.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class DBProvider {
    /**
     * 获取数据库连接对象Connection
     *
     * @return Connection对象
     */
    public static Connection getConn() {
        // 返回值
        Connection conn = null;
        // （1）注册或者实例化jdbc的驱动类；
        // 提供jdbc连接数据库的 url字符串、数据库驱动类名、用户名、密码
        // jdbc:mysql 固定格式 ； localhost ：表示的是数据库服务器的访问地址（主机名、ip，其中localhost、127.0.0.1表示本机）
        // 3306 ：mysql数据库的默认的监听客户端的端口号；端口后面是要连接的数据库名(写入自己的数据名)
        String strUrl = "jdbc:mysql://localhost:3306/javaweb202003?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false"; // url连接串
        String strDBDriverType = "com.mysql.cj.jdbc.Driver"; // 数据库驱动类名
        String strUserName = "root"; // 用户名
        String strUserPsw = "root"; // 密码

        try {
            // 加载数据库驱动类
            Class.forName("com.mysql.cj.jdbc.Driver");  // 固定写法（反射）
            // （2）获取数据库的连接对象Connection；
            conn = DriverManager.getConnection(strUrl, strUserName, strUserPsw);
        } catch (Exception e) {
            System.out.println("JDBC获取数据库连接异常：" + e.getMessage());
        }
        // 返回值
        return conn;
    }

    /**
     * 进行查询操作
     *
     * @param strSql 查询的sql语句
     * @return 查询结果集ResultSet
     */
    public static ResultSet query(String strSql) {
        // 返回结果集
        ResultSet rs = null;
        try {
            // 获取数据库连接
            Connection conn = getConn();
            // （3）获取数据库的操作对象Statement（查询器）；【执行增删改查】
            Statement st = conn.createStatement();
            // （4）执行SQL语句，获取数据操作结果或者结果集对象ResultSet
            // 获取查询结果
            rs = st.executeQuery(strSql);
        } catch (Exception e) {
            System.out.println("JDBC查询数据库操作异常：" + e.getMessage());
        }
        return rs;
    }

    /**
     * 进行查询操作
     *
     * @param strSql 查询的sql语句
     * @return 查询结果集ResultSet
     */
    public static List<Map<String, Object>> query4ListMap(String strSql) {
        // 返回结果集
        List<Map<String, Object>> lst = new ArrayList<>();
        try (// 获取数据库连接
             Connection conn = getConn();
             // （3）获取数据库的操作对象Statement（查询器）；【执行增删改查】
             Statement st = conn.createStatement();
             // （4）执行SQL语句，获取数据操作结果或者结果集对象ResultSet
             // 获取查询结果
             ResultSet rs = st.executeQuery(strSql);
        ) {
            //（5）解析结果集对象ResultSet，将ResultSet中的数据转储到List+Map的数据结构中；
            // 创建一个Map对象 // 保证有序
            Map<String, Object> mapEachRow = null;
            // 使用wile循环进行ResultSet的解析
            // next方法用于判断，在查询结果集中有没有下一条记录，在开始之前，next方法是定位在第一条记录之前的位置；
            // 获取查询结果集中的列信息
            ResultSetMetaData rsmd = rs.getMetaData();
            // 获取本次查询的结果集中有多少列
            int columnCount = rsmd.getColumnCount();
            // while遍历的是结果集的行
            while (rs.next()) {
                // 每一行的数据以键值对的形式存储在map中，每一次循环都需要新建一个map对象
                // 键值对指的是  以数据库的字段名为键   以该行数据中的该列的值为键值对的值
                mapEachRow = new LinkedHashMap<>();
                // 遍历当前行的列，下标从1开始
                for (int i = 1; i <= columnCount; i++) {
                    // 获取列名
                    String columnName = rsmd.getColumnLabel(i);  // 包含别名
                    // 通过列表获取该行该列的值
                    Object columnValue = rs.getObject(columnName);
                    // 将 键值对 列名-列值 存入当前行的map中
                    mapEachRow.put(columnName, columnValue);
                }
                // 将当前行的map存入list对象中，list中的一个map对象表示查询结果集ResultSet中的一行
                lst.add(mapEachRow);
            }

        } catch (Exception e) {
            System.out.println("JDBC查询数据库操作异常：" + e.getMessage());
        }
        return lst;
    }

    /**
     * 进行新增、修改、删除操作
     *
     * @param strSql sql语句
     * @return 操作结果影响的记录行数
     */
    public static int update(String strSql) {
        // 返回结果集
        int i = 0;
        try (// 获取数据库连接
             Connection conn = getConn();
             // （3）获取数据库的操作对象Statement（查询器）；【执行增删改查】
             Statement st = conn.createStatement();

        ) {
            // （4）执行SQL语句，获取数据操作结果
            // 执行Sql语句：insert、update、delete
            i = st.executeUpdate(strSql);
        } catch (Exception e) {
            System.out.println("JDBC查询数据库操作异常：" + e.getMessage());
        }
        return i;
    }
}
